from django.shortcuts import render


# Create your views here.
from rest_framework import generics, status, viewsets, filters
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
from rest_framework.exceptions import ValidationError
from rest_framework.decorators import action, api_view, permission_classes, authentication_classes
from rest_framework.views import APIView
from django.db.models import Q, Count, Max
from django.utils import timezone
from datetime import datetime, timedelta
import uuid
import os

from .models import Department, Doctor, Hospital, Schedule, TimeSlot, MedicalArticle
from .serializers import (
    DepartmentSerializer, DoctorSerializer, HospitalSerializer,
    ScheduleSerializer, TimeSlotSerializer, MedicalArticleSerializer,
)

# 导入推荐系统相关工具
from util.article_recommendation import collect_data, analyze_similarity, recommend_articles

# 创建Tool类用于LLM工具调用
class Tool:
    def __init__(self, name, func, description):
        self.name = name
        self.func = func
        self.description = description

class Page(PageNumberPagination):
    page_size = 20
    page_size_query_param = "page_size"
    max_page_size = 100

class DepartmentListCreateView(generics.ListCreateAPIView):
    """科室列表和创建视图"""
    queryset = Department.objects.all()
    serializer_class = DepartmentSerializer

    def get_queryset(self):
        # 获取查询参数
        parent_id = self.request.query_params.get('parent_id')
        campus = self.request.query_params.get('campus')
        
        # 构建基础查询
        queryset = Department.objects.all()
        
        # 添加过滤条件
        if parent_id:
            if parent_id == '0':  # 获取顶级科室
                queryset = queryset.filter(parent__isnull=True)
            else:
                queryset = queryset.filter(parent_id=parent_id)
        
        if campus:
            queryset = queryset.filter(campus=campus)
            
        return queryset

class DoctorListCreateView(generics.ListCreateAPIView):
    """医生列表和创建视图"""
    queryset = Doctor.objects.all()
    serializer_class = DoctorSerializer

    def get_queryset(self):
        # 获取查询参数
        department_id = self.request.query_params.get('department_id')
        campus = self.request.query_params.get('campus')
        name = self.request.query_params.get('name')
        
        # 构建基础查询
        queryset = Doctor.objects.select_related('department').all()
        
        # 添加过滤条件
        if department_id:
            queryset = queryset.filter(
                Q(department_id=department_id) | Q(department__parent_id=department_id)
            )
        if campus:
            queryset = queryset.filter(campus=campus)
        if name:
            queryset = queryset.filter(name__contains=name)
            
        return queryset

class ScheduleListView(generics.ListAPIView):
    """获取医生排班列表视图"""
    serializer_class = ScheduleSerializer
    
    def get_queryset(self):
        # 获取查询参数
        department_id = self.request.query_params.get('department_id')
        date = self.request.query_params.get('date')
        
        # 构建基础查询
        queryset = Schedule.objects.select_related('doctor').all()

        # 添加过滤条件
        if department_id:
            queryset = queryset.filter(doctor__department_id=department_id)
        if date:
            queryset = queryset.filter(date=date)
        
        # 只返回可预约的排班
        queryset = queryset.filter(status='available')
        
        return queryset.order_by('date')

class DoctorScheduleView(generics.ListAPIView):
    """获取指定医生的排班信息"""
    serializer_class = ScheduleSerializer
    
    def get_queryset(self):
        doctor_id = self.request.query_params.get('doctor_id')
        start_date = self.request.query_params.get('start_date')
        end_date = self.request.query_params.get('end_date')
        
        queryset = Schedule.objects.all()
        
        if doctor_id:
            queryset = queryset.filter(doctor_id=doctor_id)
        if start_date:
            queryset = queryset.filter(date__gte=start_date)
        if end_date:
            queryset = queryset.filter(date__lte=end_date)
            
        return queryset.order_by('date')

class TimeSlotListView(generics.ListAPIView):
    """获取预约时间段列表视图"""
    serializer_class = TimeSlotSerializer

    def get_queryset(self):
        schedule_id = self.request.query_params.get('schedule_id')
        doctor_id = self.request.query_params.get('doctor_id')
        date = self.request.query_params.get('date')
        
        queryset = TimeSlot.objects.all()
        
        if schedule_id:
            # 如果直接提供了排班ID
            return queryset.filter(schedule_id=schedule_id)
        elif all([doctor_id, date]):
            # 通过医生ID和日期查询
            schedule = Schedule.objects.filter(
                doctor_id=doctor_id,
                date=date,
                status='available'
            ).first()
            
            if schedule:
                return queryset.filter(schedule=schedule)
        
        return TimeSlot.objects.none()

class MedicalArticleViewSet(viewsets.ModelViewSet):
    """医疗文章视图集"""
    queryset = MedicalArticle.objects.all()
    serializer_class = MedicalArticleSerializer
    pagination_class = Page
    filter_backends = [filters.SearchFilter]
    search_fields = ['title', 'content', 'tags']
    
    def get_queryset(self):
        """获取文章列表，支持过滤"""
        queryset = super().get_queryset()
        
        # 支持按部门和标签过滤
        department_id = self.request.query_params.get('department_id')
        tag = self.request.query_params.get('tag')
        status_value = self.request.query_params.get('status', 'published')  # 默认只显示已发布
        
        if department_id:
            queryset = queryset.filter(department_id=department_id)
        if tag:
            queryset = queryset.filter(tags__contains=tag)
        if status_value:
            queryset = queryset.filter(status=status_value)
            
        return queryset
    
    @action(detail=True, methods=['post'])
    def view(self, request, pk=None):
        """增加文章浏览次数"""
        article = self.get_object()
        article.view_count += 1
        article.save(update_fields=['view_count'])
        return Response({'status': 'success', 'view_count': article.view_count})
    
    @action(detail=True, methods=['post'])
    def like(self, request, pk=None):
        """文章点赞"""
        article = self.get_object()
        article.like_count += 1
        article.save(update_fields=['like_count'])
        return Response({'status': 'success', 'like_count': article.like_count})

class ArticleRecommendationView(APIView):
    """文章推荐视图"""
    
    def get(self, request):
        """获取推荐文章列表"""
        # 获取热门文章（浏览量最高的10篇）
        hot_articles = MedicalArticle.objects.filter(
            status='published'
        ).order_by('-view_count')[:10]
        
        # 获取最新文章（最近发布的5篇）
        latest_articles = MedicalArticle.objects.filter(
            status='published'
        ).order_by('-created_at')[:5]
        
        # 返回结果
        hot_serializer = MedicalArticleSerializer(hot_articles, many=True)
        latest_serializer = MedicalArticleSerializer(latest_articles, many=True)
        
        return Response({
            'hot_articles': hot_serializer.data,
            'latest_articles': latest_serializer.data
        })

class ArticleDetailView(APIView):
    """文章详情视图"""
    
    def get(self, request, article_id):
        """获取文章详情"""
        try:
            article = MedicalArticle.objects.get(id=article_id)
            serializer = MedicalArticleSerializer(article)
            
            # 增加浏览次数
            article.view_count += 1
            article.save(update_fields=['view_count'])
            
            # 获取相关文章（同一科室或相同标签）
            related_articles = MedicalArticle.objects.filter(
                Q(department=article.department) | Q(tags__contains=article.tags.split(',')[0] if article.tags else ''),
                status='published'
            ).exclude(id=article_id).order_by('-created_at')[:5]
            
            related_serializer = MedicalArticleSerializer(related_articles, many=True)
            
            return Response({
                'article': serializer.data,
                'related_articles': related_serializer.data
            })
        except MedicalArticle.DoesNotExist:
            return Response({'error': '文章不存在'}, status=status.HTTP_404_NOT_FOUND)

class ArticleRecommendationAPIView(APIView):
    """基于ES的文章推荐API视图"""
    
    def get(self, request):
        """获取文章推荐"""
        try:
            # 从ES中获取推荐文章
            from .es_utils.api import get_article_recommendations
            keyword = request.query_params.get('keyword', '')
            department_id = request.query_params.get('department_id')
            
            recommendations = get_article_recommendations(keyword, department_id)
            return Response(recommendations)
        except Exception as e:
            # 如果ES出错，回退到数据库查询
            articles = MedicalArticle.objects.filter(
                status='published'
            ).order_by('-created_at')[:10]
            
            serializer = MedicalArticleSerializer(articles, many=True)
            return Response(serializer.data)

# #配置es将数据库导入es
# from elasticsearch import Elasticsearch
# class ESView(APIView):
#     def get(self, request):
#         es = Elasticsearch()
#         es.indices.create(index='medical_article', ignore=400)
#         return Response({"message": "ES索引创建成功"})
from elasticsearch import Elasticsearch
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny
from django.http import JsonResponse
from .models import MedicalArticle
import json

@api_view(['GET'])
@permission_classes([AllowAny])
def import_articles_to_es(request):
    """将所有文章导入/同步到Elasticsearch的API端点"""
    try:
        # 创建ES连接
        es = Elasticsearch('http://localhost:9200/')
        index_name = 'medical_articles'
        
        # 每次都重建索引，确保数据一致性
        if es.indices.exists(index=index_name):
            es.indices.delete(index=index_name)
            
        # 创建索引配置
        index_settings = {
            "settings": {"number_of_shards": 1, "number_of_replicas": 0},
            "mappings": {
                "properties": {
                    "id": {"type": "keyword"},
                    "title": {"type": "text", "analyzer": "standard"},
                    "content": {"type": "text", "analyzer": "standard"},
                    "author": {"type": "text"},
                    "department_name": {"type": "keyword"},
                    "tags": {"type": "text", "analyzer": "standard"},
                    "status": {"type": "keyword"},
                    "view_count": {"type": "integer"},
                    "like_count": {"type": "integer"},
                    "created_at": {"type": "date"},
                    "updated_at": {"type": "date"}
                }
            }
        }
        
        # 创建索引
        es.indices.create(index=index_name, body=index_settings)
        
        # 查询所有文章
        articles = MedicalArticle.objects.select_related('department').all()
        count = articles.count()
        
        # 导入数据到ES
        bulk_data = []
        for article in articles:
            # 构建索引操作和文档数据
            bulk_data.append({"index": {"_index": index_name, "_id": str(article.id)}})
            bulk_data.append({
                "id": article.id,
                "title": article.title,
                "content": article.content,
                "author": article.author,
                "department_name": article.department.name if article.department else "",
                "tags": article.tags,
                "status": article.status,
                "view_count": article.view_count,
                "like_count": article.like_count,
                "created_at": article.created_at.isoformat() if article.created_at else None,
                "updated_at": article.updated_at.isoformat() if article.updated_at else None
            })
        
        if bulk_data:
            # 执行批量导入
            es.bulk(body=bulk_data, refresh=True)
        
        return JsonResponse({
            'status': 'success',
            'message': f'成功导入/同步 {count} 篇文章到Elasticsearch',
            'index_name': index_name
        })
        
    except Exception as e:
        import traceback
        return JsonResponse({
            'status': 'error',
            'message': f'导入失败: {str(e)}',
            'traceback': traceback.format_exc()
        }, status=500)


@api_view(['GET'])
@permission_classes([AllowAny])
def search_articles(request):
    """基于Elasticsearch的文章搜索API"""
    query = request.GET.get('query')
    if not query:
        return JsonResponse({
            'status': 'error',
            'message': '请提供搜索关键词'
        }, status=400)
    
    try:
        # 创建ES连接
        es = Elasticsearch('http://localhost:9200/')
        
        # 检查索引是否存在
        index_name = 'medical_articles'
        if not es.indices.exists(index=index_name):
            return JsonResponse({
                'status': 'error',
                'message': 'ES索引不存在，请先调用导入API同步数据'
            }, status=500)
        
        # 构建搜索查询
        search_body = {
            "query": {
                "multi_match": {
                    "query": query,
                    "fields": ["title^3", "content^2", "tags"],
                    "fuzziness": "AUTO"
                }
            },
            "highlight": {
                "fields": {
                    "title": {},
                    "content": {}
                }
            }
        }
        
        # 执行搜索
        response = es.search(
            index=index_name,
            body=search_body,
            size=20
        )
        
        # 处理结果
        hits = response["hits"]["hits"]
        results = []
        
        for hit in hits:
            source = hit["_source"]
            
            # 获取高亮内容或使用原内容
            highlighted_content = ""
            if "highlight" in hit:
                if "content" in hit["highlight"]:
                    highlighted_content = "...".join(hit["highlight"]["content"])
                elif "title" in hit["highlight"]:
                    highlighted_content = "...".join(hit["highlight"]["title"])
                    
            if not highlighted_content and "content" in source:
                # 如果没有高亮，取前100个字符
                highlighted_content = source["content"][:100] + "..." if len(source["content"]) > 100 else source["content"]
                
            # 构建结果数据
            article_dict = {
                'id': source.get("id"),
                'title': source.get("title"),
                'author': source.get("author"),
                'department': source.get("department_name"),
                'tags': source.get("tags"),
                'view_count': source.get("view_count"),
                'like_count': source.get("like_count"),
                'created_at': source.get("created_at"),
                'content_preview': highlighted_content,
                'content': source.get("content"),
                'score': hit["_score"]
            }
            
            results.append(article_dict)
        
        return JsonResponse({
            'status': 'success',
            'count': response["hits"]["total"]["value"] if "value" in response["hits"]["total"] else response["hits"]["total"],
            'results': results
        })
        
    except Exception as e:
        import traceback
        return JsonResponse({
            'status': 'error',
            'message': f'搜索失败: {str(e)}',
            'traceback': traceback.format_exc()
        }, status=500)

@api_view(['GET'])
@permission_classes([AllowAny])
def sync_control(request):
    """控制MySQL-ES实时同步"""
    from background.mysql_es_sync import sync_instance
    import threading
    
    action = request.GET.get('action', 'status')
        
    if action == 'start':
        # 检查同步是否已在运行
        if sync_instance.is_running:
            return JsonResponse({
                'status': 'info',
                'message': '同步进程已经在运行'
            })
            
        # 在后台线程启动同步
        def run_sync_in_background():
            sync_instance.start_sync()
            
        sync_thread = threading.Thread(target=run_sync_in_background)
        sync_thread.daemon = True
        sync_thread.start()
        
        return JsonResponse({
            'status': 'success',
            'message': '实时同步进程已启动'
        })
        
    elif action == 'stop':
        if not sync_instance.is_running:
            return JsonResponse({
                'status': 'info',
                'message': '同步进程未运行'
            })
            
        sync_instance.stop_sync()
        return JsonResponse({
            'status': 'success',
            'message': '实时同步进程已停止'
        })
        
    elif action == 'rebuild':
        success, message = sync_instance.rebuild_index()
            
        return JsonResponse({
            'status': 'success' if success else 'error',
            'message': message
        })
        
    elif action == 'status':
        return JsonResponse({
            'status': 'info',
            'is_running': sync_instance.is_running,
            'message': '实时同步进程正在运行' if sync_instance.is_running else '实时同步进程未运行'
        })
    
    else:
        return JsonResponse({
            'status': 'error',
            'message': f'未知操作: {action}',
            'available_actions': ['start', 'stop', 'rebuild', 'status']
        }, status=400)
